package com.tutu.service.impl;

import com.tutu.controller.CommonsController;
import com.tutu.core.Constant;
import com.tutu.core.api.CodeDictApiUrls;
import com.tutu.core.api.DataApiUrls;
import com.tutu.entity.vo.BaseVo;
import com.tutu.entity.vo.CodeDictVo;
import com.tutu.service.CodeDictService;
import com.tutu.utils.BaseUtil;
import com.tutu.utils.HttpRequestUtil;
import com.tutu.utils.JsonUtil;
import com.tutu.utils.UnicodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class CodeDictServiceImpl implements CodeDictService {

    @Override
    public Map<String, Object> pageByParams(String type, String keyWord, Integer pageNum, Integer pageSize) {
        return HttpRequestUtil.getOnlyData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.page, "type=" + type + "&keyWord=" + UnicodeUtil.unicodeEncode(keyWord) + "&pageNum=" + pageNum + "&pageSize=" + pageSize);
    }

    @Override
    public Map<String, Object> getInfoById(Integer id) {
        return HttpRequestUtil.getOnlyData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.info, "id=" + id);
    }

    @Override
    public Map<String, Object> saveInfo(HttpServletRequest request, Integer id, String type, String code, String name, String unit) {
        LogInfoServiceImpl.saveLogInfo(request, "编辑设备参数，ID：" + id + "，类型：" + type + "，编码：" + code + "，名称：" + name + "，单位：" + unit);

        String url = CodeDictApiUrls.base_prefix + CodeDictApiUrls.update;

        if (null == id) url = CodeDictApiUrls.base_prefix + CodeDictApiUrls.create;

        Map<String, Object> map = HttpRequestUtil.getCompleteData(url, "id=" + id + "&type=" + (BaseUtil.isNotBlank(type) ? type : Constant.DATA_TYPE) + "&code=" + code + "&name=" + UnicodeUtil.unicodeEncode(name) + "&unit=" + UnicodeUtil.unicodeEncode(unit));

        loadCacheData();

        return map;
    }

    @Override
    public Map<String, Object> deleteById(HttpServletRequest request, Integer id) {
        LogInfoServiceImpl.saveLogInfo(request, "删除设备参数，ID：" + id);

        Map<String, Object> map = HttpRequestUtil.getCompleteData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.delete, "id=" + id);

        loadCacheData();

        return map;
    }

    @Override
    public Map<String, Object> batchDel(HttpServletRequest request, String ids) {
        LogInfoServiceImpl.saveLogInfo(request, "批量删除设备参数，IDS：" + ids);

        Map<String, Object> map = HttpRequestUtil.getCompleteData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.batchDel, "ids=" + ids);

        loadCacheData();

        return map;
    }

    @Override
    public Map<String, Object> batchUpdate(HttpServletRequest request, String type, String codeDictCodes, String unit) {
        LogInfoServiceImpl.saveLogInfo(request, "批量更新设备参数，类型：" + type + "，编码：" + codeDictCodes + "，单位：" + unit);

        Map<String, Object> map = HttpRequestUtil.getCompleteData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.batchUpdate, "type=" + (BaseUtil.isBlank(type) ? Constant.DATA_TYPE : type) + "&codeDictCodes=" + codeDictCodes + "&unit=" + UnicodeUtil.unicodeEncode(unit));

        loadCacheData();

        return map;
    }

    @Override
    public List<BaseVo> findTypeList() {
        List<BaseVo> list = new ArrayList<>();
        Map<String, Object> map;

        for (Object o : HttpRequestUtil.getListData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.findTypeList, "")) {
            map = JsonUtil.json2Map(o);

            if (map.containsKey("id")) list.add(new BaseVo(Integer.parseInt(map.get("id") + ""), map.get("type") + ""));
        }

        return list;
    }

    @Override
    public List<CodeDictVo> findDataList(String deviceCode, Integer type) {
        List<CodeDictVo> list = new ArrayList<>();

        if (BaseUtil.isBlank(deviceCode)) return list;

        Map<String, Object> map;
        List<String> codeDictCodeList = new ArrayList<>();
        CodeDictVo tempCdv;

        for (Object o : HttpRequestUtil.getListData(DataApiUrls.base_prefix + DataApiUrls.getInfoByDeviceCodeAndType, "deviceCode=" + deviceCode + "&type=" + (null == type ? Constant.TIME_DATA_TYPE : type))) {
            map = JsonUtil.json2Map(o);

            if (map.containsKey("code")) {
                tempCdv = changeInfo(map);

                if (tempCdv.getStatus().equals(Constant.CHECK_STATUS_DEFAULT)) continue;

                codeDictCodeList.add(tempCdv.getCode());

                list.add(tempCdv);
            }
        }

        Collections.sort(codeDictCodeList);

        List<CodeDictVo> tempList = new ArrayList<>();

        for (String codeDictCode : codeDictCodeList)
            for (CodeDictVo codeDictVo : list)
                if (codeDictCode.equals(codeDictVo.getCode())) tempList.add(codeDictVo);

        // 重新排列，将时间固定放在第一个
        CodeDictVo cdv = null;

        for (CodeDictVo codeDictVo : tempList)
            if (codeDictVo.getCode().equals("CP_DataTime")) {
                cdv = codeDictVo;

                tempList.remove(codeDictVo);

                break;
            }

        if (null != cdv) tempList.add(0, cdv);

        CommonsController.deviceCodeDictMap.put(deviceCode + "_" + type, tempList);

        return tempList;
    }

    CodeDictVo changeInfo(Map<String, Object> map) {
        CodeDictVo cdv = new CodeDictVo();

        if (map.containsKey("id")) cdv.setId(Integer.parseInt(map.get("id") + ""));
        if (map.containsKey("type")) cdv.setType(map.get("type") + "");
        if (map.containsKey("code")) cdv.setCode(map.get("code") + "");
        if (map.containsKey("name")) cdv.setName(map.get("name") + "");
        if (map.containsKey("unit")) cdv.setUnit(map.get("unit") + "");
        if (map.containsKey("status")) cdv.setStatus(Integer.parseInt(map.get("status") + ""));

        // 时间默认显示
        if (cdv.getCode().equals("CP_DataTime")) cdv.setStatus(Constant.CHECK_STATUS_SUCCESS);

        return cdv;
    }

    @Override
    public Map<String, Object> syncData(HttpServletRequest request) {
        LogInfoServiceImpl.saveLogInfo(request, "同步设备参数");

        Map<String, Object> map;

        if (CommonsController.needSync("codeDict")) {
            map = HttpRequestUtil.getSyncData(1);
        } else {
            map = BaseUtil.defaultErrorInfo(null);
        }

        loadCacheData();

        return map;
    }

    @Override
    public void loadCacheData() {
        CommonsController.baseCodeDictMap.clear();
        Map<String, Object> map;

        for (Object o : HttpRequestUtil.getListData(CodeDictApiUrls.base_prefix + CodeDictApiUrls.list, "type=" + Constant.DATA_TYPE)) {
            map = JsonUtil.json2Map(o);

            CommonsController.baseCodeDictMap.put(map.get("code") + "", changeData(map));
        }

        if (CommonsController.baseCodeDictMap.size() == 0) {
            try {
                log.info("设备参数信息请求失败，3秒后自动重试...");

                Thread.sleep(3000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            loadCacheData();
        }

        log.info("共计加载" + CommonsController.baseCodeDictMap.size() + "条设备参数信息...");
    }

    static CodeDictVo changeData(Map<String, Object> tempMap) {
        CodeDictVo codeDict = new CodeDictVo();

        try {
            if (tempMap.containsKey("id")) {
                codeDict.setId(Integer.parseInt(tempMap.get("id") + ""));
                codeDict.setType(Constant.DATA_TYPE);
                codeDict.setCode(tempMap.get("code") + "");
                codeDict.setName(tempMap.get("name") + "");
                if (tempMap.containsKey("unit")) codeDict.setUnit(tempMap.get("unit") + "");
                if (tempMap.containsKey("status")) codeDict.setStatus(Integer.parseInt(tempMap.get("status") + ""));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return codeDict;
    }
}
